//
//  STDSBaseEffect.hpp
//  STDRenderSDK
//
//  Created by 陈学明 on 2023/3/13.
//  Copyright © 2023 陈学明. All rights reserved.
//

#ifndef STDSBaseEffect_hpp
#define STDSBaseEffect_hpp

//#include <stdio.h>

#include "Manager/STDSGLContext.hpp"
#include <Basic/Attrib/STDSAttribRect.hpp>
#include <Basic/graphic/STDSObject.h>

enum STDSEffectType {
    STDSEffectTypeDefault = 1, // 默认效果
    STDSEffectTypeTransformation = 2, // 基础变换
    STDSEffectTypeHotShader = 3, // 热加载效果
    STDSEffectTypeGraphic = 4, // 热加载效果，图结构
    STDSEffectTypeBlend = 5, // 混合模式
    STDSEffectTypeGrain = 6,
    STDSEffectTypeGaussianBlur = 7,
    STDSEffectTypeHairColor = 8,
    STDSEffectTypeContrast = 9,
    STDSEffectTypeGlowLight = 10,
    STDSEffectTypeVignette = 11,
    STDSEffectTypeColorGrain = 12,
    STDSEffectTypeLightArea = 13,
    STDSEffectTypeWhiteBalance = 14,
    STDSEffectTypeMixMask = 15,
    STDSEffectTypeSkinDetect = 16,
    STDSEffectTypeSkinLutDetect = 17,
    STDSEffectTypeSkinWiten = 18,
    STDSEffectTypeGlowColor = 19,
    STDSEffectTypeMosaic = 20,
    STDSEffectTypeStroke = 21,
    STDSEffectTypeFill = 22,
    STDSEffectTypeMaskKey = 23,
    STDSEffectTypePuzzleUnit = 24, // 拼图单元
    STDSEffectTypePuzzleStars = 25,
    STDSEffectTypeSolidColor = 26,
    STDSEffectTypePuzzleGlass = 27, // 拼图毛玻璃效果
    STDSEffectTypePuzzleCartoon = 28, // 拼图漫画效果
    STDSEffectTypeBilateralBlur = 29,
    STDSEffectTypeGlassTile = 30,
    STDSEffectTypePictrueDissip = 31, // 图片消散效果
    STDSEffectTypeHairPainter = 32, // 染发
    STDSEffectTypeCloneStamp = 33, // 仿制图章
    STDSEffectTypeLut = 34, // 颜色查找表
};

/// 效果基类
class STDSBaseEffect: public STDSObject {
public:
    STDSBaseEffect() {
        mEffectType = STDSEffectTypeDefault;
    }
    
    virtual ~STDSBaseEffect() {
//        printf("dealloc--STDSBaseEffect\n");
    }
    
    virtual void initGL() {
        mProgram = mContext->getProgram(kShaderSRCDefault);
    }
    
    virtual void unInitGL() {
        mProgram = nullptr;
    }
public:
    virtual void setFloatArguments(const char *name, float *floatValue, int n) {
        
    }
    
    virtual void setIntArtuments(const char *name, int *intValue, int n) {
        
    }
    
    virtual void setStringArtuments(const char *name, const char *stringValue) {
        
    }
    
    virtual void setBitmapArguments(const char *name, const char *data, int width, int height) {
        
    }
    
    virtual void setTexIdArguments(const char *name, unsigned int texId, int width, int height) {
        
    }
    
    virtual bool checkStatus(const char *label) {
        return true;
    }
    
    virtual void setTexture(shared_ptr<STDSTexture> tex) {
        mTexture = tex;
    }
    
    virtual void setBodyTexture(shared_ptr<STDSTexture> tex) {
        mBodyTexture = tex;
    }
    
    virtual void setMatT(glm::mat4 &matT) {
        mMatT = matT;
    }
    
    virtual void setMatV(glm::mat4 &matV) {
        mMatV = matV;
    }
    
    virtual void draw() {
        
    }
    
    virtual void drawTexture(GLuint texId) {
        auto program = this->getProgram();
        program->use();
        if (mTexture != nullptr) {
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, texId);
            mProgram->setUniform(program->getUniform("uTexture"), 0);
        }
        mAtbRect.setPosVex(program->getAttrib("aPos"));
        mAtbRect.setPosTex(program->getAttrib("aTexCoord"));
        mAtbRect.draw();
        program->unuse();
    }
    
    void setContext(shared_ptr<STDSGLContext> ctx) {
        mContext = ctx;
        initGL();
    }
    
    shared_ptr<STDSGLContext> getContext() {
        return mContext;
    }
    
    bool isVisible() {
        return mIsVisible;
    }
    
    void setVisible(bool visible) {
        mIsVisible = visible;
    }
    
    virtual void setPrograss(float prograss) {
        mCurPrograss = prograss;
    }
    
    virtual float getPrograss() {
        return mCurPrograss;
    }
    
    shared_ptr<STDSShaderProgram> getProgram() {
        if (mProgram == nullptr) {
            mProgram = mContext->getProgram(kShaderSRCDefault);
        }
        return mProgram;
    }
    
public:
    bool mIsVisible{true}; // 是否可见
    STDSEffectType mEffectType;
    float mIntensity{0.0};
    STDSAttribRect mAtbRect;
    glm::mat4 mMatT{1.0}; // 纹理坐标变换矩阵
    glm::mat4 mMatV{1.0}; // 顶点坐标变换矩阵
    shared_ptr<STDSTexture> mTexture{nullptr};
    shared_ptr<STDSTexture> mBodyTexture{nullptr};
    shared_ptr<STDSGLContext> mContext{nullptr};
    shared_ptr<STDSShaderProgram> mProgram{nullptr};
    float mCurPrograss{0.0}; // 进度
    glm::vec2 mSizeSRC{0.0, 0.0};// 进度
};
#endif /* STDSBaseEffect_hpp */
